package com.iflytek.iot.zookeeper.lock;

import com.iflytek.iot.common.exception.DistributedLockException;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author yu 2019/7/9.
 */
@Component
public class ShardReentrantLock {

    private static final Logger LOGGER = LoggerFactory.getLogger(ShardReentrantLock.class);

    private final static String ROOT_PATH_LOCK = "/rootlock";

    @Resource
    private CuratorFramework curatorFramework;

    /**
     * 分布式锁测试
     *
     * @return
     * @throws Exception
     */
    public <T> T acquireLock(ZookeeperBaseLock<T> mutex) {
        String path = ROOT_PATH_LOCK + mutex.getLockPath();
        InterProcessMutex lock = new InterProcessMutex(curatorFramework, path);
        boolean success = false;
        try {
            try {
                success = lock.acquire(mutex.getTimeout(), mutex.getTimeUnit());
            } catch (Exception e) {
                throw new DistributedLockException("obtain lock error " + e.getMessage() + ", path " + path);
            }
            if (success) {
                return mutex.execute();
            } else {
                return null;
            }
        } finally {
            try {
                if (success) {
                    lock.release();
                }
            } catch (Exception e) {
                LOGGER.error("release lock error {}, path {}", e.getMessage(), path);
            }
        }
    }
}
